package com.cdeledu.thread4.c15;

public class ObservableThread<T> extends Thread implements Observable {
	private final TaskLifecycle<T> lifecycle;
	private final Task<T> task;
	private Cycle cycle;

	/**指定Task的实现，默认情况下使用EmptyLifecycle
	 * @param task
	 */
	public ObservableThread(Task<T> task) {
		this(new TaskLifecycle.EmptyLifecycle<>(), task);
	}

	/**指定TaskLifecycle的同时指定Task
	 * @param lifecycle
	 * @param task
	 */
	public ObservableThread(TaskLifecycle<T> lifecycle, Task<T> task) {
		super();
		// Task不允许为null
		if (task == null)
			throw new IllegalArgumentException("The task is required.");
		this.lifecycle = lifecycle;
		this.task = task;
	}

	@Override
	public final void run() {
		// 在执行线程逻辑单元的时候，分别触发相应的事件
		this.update(Cycle.STARTED, null, null);
		try {
			this.update(Cycle.RUNNING, null, null);
			T result = this.task.call();
			this.update(Cycle.DONE, result, null);
		} catch (Exception e) {
			this.update(Cycle.ERROR, null, e);
		}
	}

	/**update方法用于通知事件的监听者，此时任务在执行过程中发生了什么，最主要的通知是异常的处理。如果监听者也就是TaskLifecycle，在响应某个事件的过程中出现了意外，
	 * 则会导致任务的正常执行受到影响，因此需要进行异常捕获，并忽略这些异常信息以保证TaskLifecycle的实现不影响任务的正确执行，但是如果任务执行过程中出现错误并且抛出了异常，
	 * 那么update方法就不能忽略该异常，需要继续抛出异常，保持与call方法同样的意图
	 * @param cycle
	 * @param result
	 * @param e
	 */
	private void update(Cycle cycle, T result, Exception e) {
		this.cycle = cycle;
		if (lifecycle == null)
			return;
		try {
			switch (cycle) {
			case STARTED:
				this.lifecycle.onStart(currentThread());
				break;
			case RUNNING:
				this.lifecycle.onRunning(currentThread());
				break;
			case DONE:
				this.lifecycle.onFinish(currentThread(), result);
				break;
			case ERROR:
				this.lifecycle.onError(currentThread(), e);
				break;
			}
		} catch (Exception ex) {
			if (cycle == Cycle.ERROR) {
				throw ex;
			}
		}
	}

	@Override
	public Cycle getCycle() {
		return this.cycle;
	}
	
}